/**
 * 上传请求模块
 * 提供上传请求相关的功能
 */
import { ElMessage } from 'element-plus';
import { uploadImage } from '@/api/modules/commodity';
import { compressImage } from './imageCompressor';

/**
 * 自定义上传请求
 * @param {Object} options - 上传选项
 * @param {File} options.file - 文件对象
 * @param {Function} options.onProgress - 进度回调
 * @param {Function} options.onSuccess - 成功回调
 * @param {Function} options.onError - 错误回调
 * @param {Object} config - 上传配置
 * @param {Boolean} config.useFormData - 是否使用FormData格式提交
 * @param {String} config.name - 文件参数名
 * @param {Object} config.data - 上传时附带的额外参数
 * @param {Boolean} config.enableCompress - 是否启用压缩
 * @param {Number} config.compressSize - 压缩阈值（MB）
 * @param {Number} config.maxSize - 文件大小限制（MB）
 * @param {Function} config.httpRequest - 自定义上传请求方法
 * @param {Function} config.getFileList - 获取当前文件列表的方法
 * @param {Function} config.updateModelValue - 更新文件列表的方法
 * @param {Function} config.formatOutputData - 格式化输出数据的方法
 * @param {Function} config.emitUrlsChange - 发送URL更新事件的方法
 * @returns {Object} - 上传控制对象，包含abort方法
 */
export const customHttpRequest = async (options, config) => {
  // 如果外部提供了自定义的上传方法，则使用外部提供的
  if (config.httpRequest) {
    console.log('使用外部自定义上传方法');
    return config.httpRequest(options);
  }
  
  // 否则使用内部上传逻辑
  console.log('使用内部上传方法');
  const { file, onProgress, onSuccess, onError } = options;
  
  // 确保文件对象存在
  if (!file) {
    console.warn('上传失败：文件对象无效');
    onError(new Error('文件对象无效'));
    return;
  }
  
  // 为这个上传操作设置一个唯一标识，用于防止竞态条件
  const uploadId = Date.now() + '_' + file.uid;
  file._uploadId = uploadId;
  
  console.log(`开始处理图片 [${uploadId}]:`, file.name);
  
  // 创建取消上传的控制对象
  const controller = {
    abort() {
      console.log(`[${uploadId}] 上传已取消`);
      if (loadingMsg) loadingMsg.close();
      if (progressInterval) clearInterval(progressInterval);
    }
  };
  
  // 检查文件是否需要压缩
  let fileToUpload = file;
  let loadingMsg = null;
  let progressInterval = null;
  
  try {
    // 获取文件大小（MB）
    const fileSizeMB = file.size / 1024 / 1024;
    const needCompress = config.enableCompress && fileSizeMB > config.compressSize;
    
    // 打印日志
    console.log('文件检查:', file.name, '大小:', fileSizeMB.toFixed(2), 'MB', '限制:', config.maxSize, 'MB',
      '需要压缩:', needCompress, '(启用压缩:', config.enableCompress, ', 压缩阈值:', config.compressSize, 'MB)');
    
    // 需要压缩的情况
    if (needCompress) {
      // 显示压缩中提示
      loadingMsg = ElMessage({
        message: '图片压缩中，请稍候...',
        type: 'info',
        duration: 0
      });
      
      try {
        // 执行压缩
        const compressedFile = await compressImage(file, {
          maxSize: config.maxSize,
          compressSize: config.compressSize,
          enableCompress: config.enableCompress,
          compressQuality: config.compressQuality,
          maxCompressTries: config.maxCompressTries
        });
        
        // 更新要上传的文件
        fileToUpload = compressedFile;
        
        console.log(`压缩完成: ${fileSizeMB.toFixed(2)}MB -> ${(compressedFile.size / 1024 / 1024).toFixed(2)}MB`);
        
        // 关闭压缩提示
        loadingMsg.close();
        loadingMsg = null;
      } catch (err) {
        // 关闭提示
        if (loadingMsg) {
          loadingMsg.close();
          loadingMsg = null;
        }
        
        // 避免显示重复的"文件大小超过"错误提示
        const errorMessage = err.message && err.message.includes('图片大小不能超过') ? 
          '图片压缩失败' : `图片压缩失败: ${err.message}`;
        ElMessage.error(errorMessage);
        console.error('压缩失败:', err);
        
        // 压缩失败时报错
        onError(new Error(errorMessage));
        return controller;
      }
    }
    
    // 显示上传中的消息提示
    loadingMsg = ElMessage({
      message: '图片上传中，请稍候...',
      type: 'info',
      duration: 0
    });
    
    // 模拟上传进度
    let percent = 0;
    progressInterval = setInterval(() => {
      percent += 5;
      if (percent <= 90) {
        onProgress({ percent });
      } else {
        clearInterval(progressInterval);
        progressInterval = null;
      }
    }, 200);
    
    // 执行上传任务
    try {
      let result;
      
      if (config.useFormData) {
        // 创建FormData对象
        const formData = new FormData();
        formData.append(config.name, fileToUpload);
        
        // 添加额外参数
        Object.keys(config.data).forEach(key => {
          formData.append(key, config.data[key]);
        });
        
        // 调用上传API
        result = await uploadImage(formData);
      } else {
        // 如果不使用FormData，直接上传文件
        result = await uploadImage(fileToUpload);
      }
      
      // 上传已完成，检查是否是最新的上传操作
      if (file._uploadId !== uploadId) {
        console.warn(`[${uploadId}] 上传操作已被更新的请求替代，忽略旧请求结果`);
        if (loadingMsg) loadingMsg.close();
        return controller;
      }
      
      // 清除进度定时器
      if (progressInterval) {
        clearInterval(progressInterval);
        progressInterval = null;
      }
      
      // 上传完成，设置为100%
      onProgress({ percent: 100 });
      
      // 关闭加载提示
      if (loadingMsg) {
        loadingMsg.close();
        loadingMsg = null;
      }
      
      // 处理上传成功
      if (result && (result.code === 200 || result.code === '200')) {
        console.log(`[${uploadId}] 图片上传成功，响应数据:`, result);
        
        // 获取图片URL（直接使用data字段，它本身就是URL）
        const imageUrl = result.data;
        
        // 创建成功响应
        const successResponse = {
          ...result,
          url: imageUrl
        };
        
        // 获取最新的文件列表 - 在调用onSuccess前先更新文件
        const latestFileList = config.getFileList();
        const fileIndex = latestFileList.findIndex(f => f.uid === file.uid);
        
        if (fileIndex !== -1) {
          // 先更新文件URL为服务器URL
          latestFileList[fileIndex] = {
            ...latestFileList[fileIndex],
            url: imageUrl,
            response: result,
            status: 'success'  // 确保状态更新为success
          };
          
          // 在更新前打印调试信息，确保URL已正确更新
          console.log(`[${uploadId}] 在onSuccess前更新文件URL: 从 ${latestFileList[fileIndex].url || '无'} 到 ${imageUrl}`);
          
          // 立即更新文件列表状态
          config.updateModelValue(config.formatOutputData(latestFileList));
        }
        
        // 然后调用onSuccess，让el-upload组件知道上传成功
        onSuccess(successResponse);
        
        // 弹出成功提示
        ElMessage.success('图片上传成功');
        
        // 再次获取最新的文件列表（可能在onSuccess回调中被修改）
        const updatedFileList = config.getFileList();
        const updatedFileIndex = updatedFileList.findIndex(f => f.uid === file.uid);
        
        if (updatedFileIndex !== -1) {
          // 检查URL是否还是服务器URL，如果不是，再次更新
          if (updatedFileList[updatedFileIndex].url !== imageUrl) {
            console.warn(`[${uploadId}] URL在onSuccess后被覆盖，从 ${imageUrl} 变为 ${updatedFileList[updatedFileIndex].url}，重新更正`);
            
            // 再次更新文件URL为服务器URL
            updatedFileList[updatedFileIndex] = {
              ...updatedFileList[updatedFileIndex],
              url: imageUrl,
              response: result,
              status: 'success'
            };
            
            // 更新文件列表状态
            config.updateModelValue(config.formatOutputData(updatedFileList));
          }
        } else if (fileIndex !== -1) {
          console.warn(`[${uploadId}] 文件在onSuccess后丢失，尝试重新添加`);
          
          // 尝试将之前准备的文件添加回来
          updatedFileList.push(latestFileList[fileIndex]);
          config.updateModelValue(config.formatOutputData(updatedFileList));
        } else {
          console.warn(`[${uploadId}] 找不到对应上传的文件，无法更新URL`);
        }
        
        // 创建简单的URL数组并发送urlsChange事件
        const urlList = updatedFileList
          .filter(f => (f.status === 'success' || f.url === imageUrl) && f.url)
          .map(f => f.url);
        
        console.log(`[${uploadId}] 发送URL列表更新事件:`, urlList);
        config.emitUrlsChange(urlList);
      } else {
        // 上传失败
        const errorMsg = result?.message || '未知错误';
        ElMessage.error(`图片上传失败: ${errorMsg}`);
        console.error(`[${uploadId}] 图片上传失败，响应数据:`, result);
        onError(new Error(errorMsg));
      }
    } catch (error) {
      // 关闭加载提示
      if (loadingMsg) {
        loadingMsg.close();
        loadingMsg = null;
      }
      
      // 清除进度定时器
      if (progressInterval) {
        clearInterval(progressInterval);
        progressInterval = null;
      }
      
      // 处理异常，避免重复显示"文件大小超过"等已经显示过的错误
      const errorMessage = error.message && error.message.includes('图片大小不能超过') ? 
        '文件上传失败' : `图片上传异常: ${error.message}`;
      ElMessage.error(errorMessage);
      console.error(`[${uploadId}] 图片上传异常:`, error);
      
      onError(error);
    }
  } catch (error) {
    // 处理整体异常
    console.error('处理上传任务异常:', error);
    if (loadingMsg) loadingMsg.close();
    if (progressInterval) clearInterval(progressInterval);
    onError(error);
  }
  
  // 返回控制对象
  return controller;
};

export default {
  customHttpRequest
}; 